/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package treegenerator.arbaro;

import com.jme3.asset.AssetManager;
import com.jme3.material.Material;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture2D;
import com.jme3.texture.plugins.AWTLoader;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author jannes
 */
public class StemTextureCreator {
    protected int tiles_x,tiles_y;
    protected int tiles_top;
    protected long seed;    
    protected int tileSize;
    protected ArrayList<BufferedImage> tiles;
    protected AWTLoader awtLoader;    
    
    public StemTextureCreator(){        
        tiles = new ArrayList<BufferedImage>();        
        awtLoader = new AWTLoader();
    }
    
    public void addTile(BufferedImage tile){        
        if(tile.getWidth() == tile.getHeight()){
            if(!tiles.isEmpty()){                
                if(tileSize == tile.getWidth()){
                    tiles.add(tile);
                }
            }else{            
                tiles.add(tile);
                tileSize = tile.getWidth();
            }
        }
    }

    public ArrayList<BufferedImage> getTiles(){
        return tiles;
    }
    
    public void removeTile(BufferedImage tile){        
        tiles.remove(tile);        
    }
    
    public long getSeed() {
        return seed;
    }

    public void setSeed(long seed) {
        this.seed = seed;
    }

    public int getTiles_top() {
        return tiles_top;
    }

    public void setTiles_top(int tiles_top) {
        this.tiles_top = tiles_top;
    }

    public int getTiles_x() {        
        return tiles_x;            
    }

    public void setTiles_x(int tiles_x) {
        if(tiles_x % 2 == 0){
            this.tiles_x = tiles_x;
        }else{
            this.tiles_x = tiles_x+1;
        }
    }

    public int getTiles_y() {
        return tiles_y;
    }

    public void setTiles_y(int tiles_y) {
        this.tiles_y = tiles_y;
    }        
    
    public int getTileCount(){
        return tiles.size();
    }
    
    public void removeAllTiles(){
        tiles.clear();
    }
    
    public Material createMaterial(AssetManager assetManager){
        return createMaterial(createImage(),assetManager);
    }
    
    public Material createMaterial(BufferedImage bi,AssetManager assetManager){
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");                         
        Texture texture = new Texture2D(awtLoader.load(bi, false));                
        mat.setTexture("ColorMap", texture);        
        return mat;
    }
    
    public BufferedImage createImage(){
        return createImage(seed);
    }
    
    public BufferedImage createImage(long seed){
        //Todo: scale factor for y (float list from size tiles_y);
        BufferedImage bi = null;
        if(!tiles.isEmpty()){
            Random random = new Random(seed);
            bi = new BufferedImage(tileSize * tiles_x, tileSize * tiles_y, BufferedImage.TYPE_INT_RGB);        
            Graphics2D g = bi.createGraphics();
            for(int x = 0; x < tiles_x; x++){
                for(int y = tiles_top; y < tiles_y; y++){
                    BufferedImage tile = tiles.get(random.nextInt(tiles.size()));                
                    g.drawImage(tile, null, tileSize*x, tileSize*y);
                }            
            }    
            for(int x = 0; x < tiles_x/2; x++){
                for(int y = 0; y < tiles_top; y++){
                    BufferedImage tile = tiles.get(random.nextInt(tiles.size()));                
                    g.drawImage(tile, null, tileSize*x, tileSize*y);                
                    g.drawImage(MirrorV(tile), null, tileSize*(tiles_x-1-x), tileSize*y);
                }
            }                        
        }else{
            bi = new BufferedImage(128,128,BufferedImage.TYPE_INT_ARGB);            
            Graphics g = bi.getGraphics(); 
            Color c = new Color(139,69,19);
            g.setColor(c);
            g.fillRect(0, 0, 128, 128);
        }
        return bi;
    }
    
    public BufferedImage MirrorV(BufferedImage InputImage) {

        BufferedImage OutputImage = null;
        OutputImage = new BufferedImage(InputImage.getWidth(), InputImage.getHeight(),BufferedImage.TYPE_3BYTE_BGR);
        
        try {
            AffineTransform tx = AffineTransform.getScaleInstance(1, -1);
            tx.translate(0, -InputImage.getHeight(null));
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
            OutputImage = op.filter(InputImage, null);
        } catch (Exception e) {            
            OutputImage = InputImage;//als het fout gaat, return de inputimage
        }
        return OutputImage;
    }

    public BufferedImage MirrorH(BufferedImage InputImage) {

        BufferedImage OutputImage = null;
        OutputImage = new BufferedImage(InputImage.getWidth(), InputImage.getHeight(),BufferedImage.TYPE_3BYTE_BGR);
        
        try {
            AffineTransform tx = AffineTransform.getScaleInstance(-1, 1);
            tx.translate(-InputImage.getWidth(null), 0);
            AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
            OutputImage = op.filter(InputImage, null);
        } catch (Exception e) {            
            OutputImage = InputImage; //als het fout gaat, return de inputimage
        }
        
        return OutputImage;
    }        
    
    
}
